<script setup lang="ts">
import updateDialog from './dialog/update/index.vue';
import { searchConfig } from './config/search-config';
import { doGetWorkingPeriodList } from '@/api/base/workCalendar/workCalender/index';
import { dayMap } from '@/views/Base/WorkCalendar/common';
import { useMouse } from '@/components/base-ui/base-table/hooks/useMouse';
import { toPx, getDom, generateLightColor } from '@/utils';
import { generateNameToLevel, mutationConfig } from '@/config/constant';
import type {
    WorkingCalendarHeaders,
    CalendarPageRecords,
    PeriodInfo,
    AdditionalProp
} from '@/api/base/workCalendar/workCalender/model/type';

// 表头拖动相关
const { tableRef, snackbarVisible, snackOverflow, snackbarText, moveOffset } = useMouse();

// 搜索组件
const searchRef = ref<SearchRef>();

/**
 * @: 获取数据相关
 */
const columnHeaders = ref<WorkingCalendarHeaders[]>([]);
const tableData = ref<CalendarPageRecords[]>([]);
const page = ref({ current: 1, size: 20 });
const total = ref(0);
const loading = ref(false);
const isRefresh = ref(false);

/**
 * @: 处理数据让表格数据条状显示
 */
const handleRecords = (tableBody: CalendarPageRecords[], tableHeader: WorkingCalendarHeaders[]) => {
    for (let i = 0; i < tableBody.length; i++) {
        const item = tableBody[i].calendars;
        for (let j = 0; j < tableHeader.length; j++) {
            const preKey = j === 0 ? null : tableHeader[j - 1]?.date; // 前一个的时间
            const key = tableHeader[j].date; // 当前的时间
            const nextKey = j < tableHeader.length ? tableHeader[j + 1]?.date : null; // 后一个时间

            if (item[key]?.periodId) {
                const CId = item[key].periodId; // 当前id
                const CName = item[key].periodInfo?.name; // 当前name
                item[key].periodInfo.tipName = CName; // 提示信息

                // 如果没有前一个或者前一个的id不等于当前id
                if (!preKey || item[preKey]?.periodId !== CId) {
                    item[key].start = true;
                }

                // 如果没有后一个或者后一个id不等于当前的id
                if (!nextKey || item[nextKey]?.periodId !== CId) {
                    item[key].end = true;
                    item[key].periodInfo.name = '';
                }

                const start = item[key].start;
                const end = item[key].end;

                // 如果即是开始又是结束说明只有一个，需要删除当前开始和结束的状态
                if (start && end) {
                    delete item[key].start;
                    delete item[key].end;
                    item[key].periodInfo.name = CName;
                }

                // 如果既不是开始也不是结束并且有前一个key，而且前一个key等于当前的key就是中间
                if (!start && !end && preKey && item[preKey]?.periodId === CId) {
                    item[key].center = true;
                    item[key].periodInfo.name = '';
                }
            }
        }
    }

    return tableBody;
};

/**
 * @: 获取数据
 */
const getWorkingPeriodList = async (reset = false) => {
    loading.value = true;
    if (reset) {
        page.value = { current: 1, size: 20 };
    }
    try {
        const { data } = await doGetWorkingPeriodList({
            ...searchRef.value?.formData,
            ...page.value
        });
        if (data) {
            columnHeaders.value = data.headers;
            const { records, current, size } = data.calendarPage;
            tableData.value = handleRecords(records, data.headers);
            page.value = { current, size };
            total.value = data.calendarPage.total;
        }
    } catch (error) {
        console.log('error', error);
    }
    loading.value = false;
    isRefresh.value = false;
};

/**
 * @: 更改条数
 */
const sizeChange = (e: number) => {
    page.value.size = e;
    getWorkingPeriodList();
};

/**
 * @: 更改页数
 */
const currentChange = (e: number) => {
    page.value.current = e;
    getWorkingPeriodList();
};

/**
 * @: 工作日历渲染
 */
const renderCalendars = (target?: PeriodInfo, key?: 'name') => {
    if (!target) return;
    if (key) {
        return target[key];
    }
    const name = target.tipName;
    const days = target.times?.reduce((pre, item) => {
        return pre + item.start + '-' + item.end + ' ';
    }, '');

    return name + ': ' + days;
};

/**
 * @: 高度相关
 */
const minHeight = ref<string | number>(0);
const defaultHeight = () => {
    if (!tableRef.value || minHeight.value) return;
    const elTop = useElementBounding(tableRef.value.$el);
    const WHeight = window.innerHeight;
    const pageSpace = 48 + 38; // .m-table 离底部距离
    const paginationDom: HTMLElement | null = getDom('.pagination');
    const elHeightArr = [elTop.top.value, +(paginationDom?.scrollHeight || 46), pageSpace];
    minHeight.value = elHeightArr.reduce((total, height) => {
        return total - height;
    }, WHeight);
};

onMounted(() => {
    getWorkingPeriodList();
    mutationTable();
});

onActivated(() => {
    getWorkingPeriodList();
});

/**
 * @: 监听dom渲染完成计算高度
 */
const mutationTable = () => {
    useMutationObserver(tableRef.value?.$el, defaultHeight, mutationConfig);
};

/**
 * @: 打开编辑弹框
 */
const updateDialogRef = ref<InstanceType<typeof updateDialog>>();
const openUpdate = (row: AdditionalProp) => {
    if (!row?.isEdit) return;
    updateDialogRef.value?.open(row);
};
</script>

<template>
    <div v-scrollbar="true" class="main header-sticky f-column f-1">
        <base-search
            ref="searchRef"
            :search-config="searchConfig"
            :resetData="getWorkingPeriodList"
            @search="getWorkingPeriodList"
        />

        <el-table
            :id="generateNameToLevel('1')"
            ref="tableRef"
            class="f-1"
            :header-cell-style="{ height: '32px' }"
            :row-style="{ height: '44px' }"
            :data="tableData"
            border
            scrollbar-always-on
        >
            <!-- 设备编码 -->
            <el-table-column
                label="设备编码"
                min-width="150px"
                prop="deviceCode"
                fixed="left"
                show-overflow-tooltip
                class-name="m-device-code"
            />

            <!-- 日期列表数据 -->
            <template v-for="item in columnHeaders" :key="item.date">
                <el-table-column
                    :label="item.day + ''"
                    :label-class-name="item.week === 7 ? 'weekColor weekHeight' : 'weekHeight'"
                    min-width="105px"
                    align="center"
                    class-name="no-resize"
                >
                    <el-table-column
                        :label="dayMap[item.week]"
                        :label-class-name="item.week === 7 ? 'weekColor weekHeight' : 'weekHeight'"
                        min-width="105px"
                        align="center"
                    >
                        <template #default="{ row }">
                            <div
                                :class="{
                                    start: row.calendars[item.date]?.start,
                                    center: row.calendars[item.date]?.center,
                                    end: row.calendars[item.date]?.end,
                                    disabled: !row.calendars[item.date]?.isEdit
                                }"
                                class="col-cell"
                                @click="openUpdate(row.calendars[item.date])"
                            >
                                <div v-if="row.calendars[item.date] === undefined"></div>

                                <div
                                    v-else-if="row.calendars[item.date].periodId === 0"
                                    class="rest"
                                >
                                    休息
                                </div>

                                <el-tooltip
                                    v-else
                                    effect="dark"
                                    :content="renderCalendars(row.calendars[item.date].periodInfo)"
                                    placement="top"
                                    :show-arrow="false"
                                    :show-after="300"
                                >
                                    <div class="col">
                                        <div>
                                            <div
                                                v-if="
                                                    renderCalendars(
                                                        row.calendars[item.date].periodInfo,
                                                        'name'
                                                    )
                                                "
                                                :style="{
                                                    backgroundColor: generateLightColor(
                                                        row.calendars[item.date].periodInfo.name,
                                                        'FF'
                                                    )
                                                }"
                                                class="dot"
                                            />
                                        </div>
                                        <div class="col__name">
                                            {{
                                                renderCalendars(
                                                    row.calendars[item.date].periodInfo,
                                                    'name'
                                                )
                                            }}
                                        </div>
                                    </div>
                                </el-tooltip>
                            </div>
                        </template>
                    </el-table-column>
                </el-table-column>
            </template>

            <template #empty>
                <QEmpty
                    ref="emptyRef"
                    :add-table-row="false"
                    :modal-mode="false"
                    :height="toPx(+minHeight - 44)"
                />
            </template>
        </el-table>

        <!-- 表格滚动条 -->
        <div class="m-table__scrollbar"></div>

        <!-- 分页器 -->
        <el-row justify="end" class="pagination">
            <el-pagination
                :current-page="page.current"
                :page-size="page.size"
                :total="total"
                background
                layout="total, slot, sizes, prev, pager, next"
                :page-sizes="[10, 20, 50, 100]"
                @size-change="sizeChange"
                @current-change="currentChange"
            >
                <template #default>
                    <q-icon
                        icon-class="gengxinqi"
                        size="16px"
                        :class="['u-pagination-icon', { 'is-active': loading }]"
                        @click="
                            () => {
                                isRefresh = true;
                                getWorkingPeriodList();
                            }
                        "
                    ></q-icon>
                </template>
            </el-pagination>
        </el-row>

        <!-- 更改弹框 -->
        <update-dialog ref="updateDialogRef" @close="getWorkingPeriodList" />

        <!-- 鼠标移入表头提示 -->
        <q-snackbar
            v-model="snackbarVisible"
            :text="snackbarText"
            :flip="snackOverflow"
            :show-arrow="true"
            :show-mask="true"
            :auto-close="false"
            :style="{ left: moveOffset.x, top: moveOffset.y }"
        />
    </div>
</template>

<style scoped lang="scss">
@include b(main) {
    padding: 1px 24px 16px;

    :deep(.weekColor) {
        color: var(--q-color-danger);
    }

    :deep(.weekHeight) {
        height: 33px !important;
        padding: 4px 0;
    }

    :deep(.el-table--border th.el-table__cell) {
        background: var(--q-bg-color-table);
        border-right: unset;
        border-bottom: unset;
    }

    :deep(
            .el-table.is-scrolling-left.el-table--border
                th.el-table-fixed-column--left.is-last-column.el-table__cell
        ) {
        border-right: unset;
    }

    :deep() {
        .el-table .el-table__header-wrapper .el-table__header .el-table__cell {
            &:not(.m-device-code) {
                .cell {
                    justify-content: center;
                }
            }
        }
    }
}

@include b(el-table) {
    --el-table-row-hover-bg-color: #fff;
    --el-table-border-color: var(--q-color-info-light-8);
}

@include b(rest) {
    margin-right: 12px;
    color: var(--q-text-color-secondary);
}

@include b(col-cell) {
    height: 24px;
    padding: 0 4px;
    margin-right: -12px;
    cursor: pointer;
}

@include b(disabled) {
    cursor: not-allowed;
}

@include b(col) {
    display: flex;
    align-items: center;
    height: 24px;
    color: var(--q-color-primary);

    @include e(name) {
        max-width: 42px;

        @include utils-ellipsis(1);
    }
}

@include b(dot) {
    width: 11px;
    height: 11px;
    margin-right: 6px;
    border-radius: 14px;
}

@include b(start) {
    background: rgb(0 102 255 / 10%);
    border-radius: 2px 0 0 2px;
}

@include b(center) {
    margin-right: -12px;
    margin-left: -12px;
    background: rgb(0 102 255 / 10%);
}

@include b(end) {
    margin-right: 0;
    margin-left: -12px;
    background: rgb(0 102 255 / 10%);
    border-radius: 0 2px 2px 0;
}

@include b(pagination) {
    padding-top: 14px;
}

@include b(u-pagination-icon) {
    margin-left: 12px;
    cursor: pointer;

    @include when('active') {
        animation: rotation 1s linear infinite;
    }
}

@include b(m-table) {
    @include e(scrollbar) {
        position: sticky;
        bottom: -35px;
        z-index: 12;
    }
}

:deep() {
    @import '@/assets/style/common/reset-border.scss';
}
</style>
